from pydantic import BaseModel, EmailStr, field_validator, ConfigDict
from typing import List, Optional
from datetime import datetime

/**
 * @file schemas.py
 * @brief Pydantic schemas for Meeting Management System API input/output validation.
 * @author Ziyi Wang
 *
 * Defines User, Room, Meeting, Token schemas for API requests and responses.
 */

# 用户相关架构
/**
 * @class UserBase
 * @brief Base schema for user.
 */
class UserBase(BaseModel):
    username: str
    email: EmailStr
    full_name: Optional[str] = None

class UserCreate(UserBase):
    /**
     * @class UserCreate
     * @brief Schema for creating a user.
     */
    password: str

class UserUpdate(BaseModel):
    /**
     * @class UserUpdate
     * @brief Schema for updating a user.
     */
    username: Optional[str] = None
    email: Optional[EmailStr] = None
    full_name: Optional[str] = None
    password: Optional[str] = None
    is_active: Optional[bool] = None

class UserInDB(UserBase):
    /**
     * @class UserInDB
     * @brief Schema for user in database.
     */
    id: int
    is_active: bool
    is_admin: bool
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)

class User(UserInDB):
    /**
     * @class User
     * @brief Schema for user response.
     */
    pass

# 会议室相关架构
/**
 * @class RoomBase
 * @brief Base schema for meeting room.
 */
class RoomBase(BaseModel):
    name: str
    capacity: int
    location: str
    facilities: Optional[str] = None

class RoomCreate(RoomBase):
    /**
     * @class RoomCreate
     * @brief Schema for creating a room.
     */
    pass

class RoomUpdate(BaseModel):
    /**
     * @class RoomUpdate
     * @brief Schema for updating a room.
     */
    name: Optional[str] = None
    capacity: Optional[int] = None
    location: Optional[str] = None
    facilities: Optional[str] = None
    is_active: Optional[bool] = None

class RoomInDB(RoomBase):
    /**
     * @class RoomInDB
     * @brief Schema for room in database.
     */
    id: int
    is_active: bool
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)

class Room(RoomInDB):
    /**
     * @class Room
     * @brief Schema for room response.
     */
    pass

# 会议相关架构
/**
 * @class MeetingBase
 * @brief Base schema for meeting.
 */
class MeetingBase(BaseModel):
    title: str
    description: Optional[str] = None
    start_time: datetime
    end_time: datetime
    room_id: int

    @field_validator('end_time')
    def end_time_must_be_after_start_time(cls, v, values):
        if 'start_time' in values.data and v <= values.data['start_time']:
            raise ValueError('结束时间必须晚于开始时间')
        return v

class MeetingCreate(MeetingBase):
    /**
     * @class MeetingCreate
     * @brief Schema for creating a meeting.
     */
    participant_ids: Optional[List[int]] = []

class MeetingUpdate(BaseModel):
    /**
     * @class MeetingUpdate
     * @brief Schema for updating a meeting.
     */
    title: Optional[str] = None
    description: Optional[str] = None
    start_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    room_id: Optional[int] = None
    is_cancelled: Optional[bool] = None
    participant_ids: Optional[List[int]] = None

class MeetingInDB(MeetingBase):
    /**
     * @class MeetingInDB
     * @brief Schema for meeting in database.
     */
    id: int
    owner_id: int
    is_cancelled: bool
    created_at: datetime
    updated_at: datetime
    
    model_config = ConfigDict(from_attributes=True)

class Meeting(MeetingInDB):
    /**
     * @class Meeting
     * @brief Schema for meeting response.
     */
    owner: User
    room: Room
    participants: List[User]

# 令牌架构
/**
 * @class Token
 * @brief Schema for JWT token response.
 */
class Token(BaseModel):
    access_token: str
    token_type: str

class TokenData(BaseModel):
    /**
     * @class TokenData
     * @brief Schema for JWT token data.
     */
    username: Optional[str] = None 